using System;
using System.Drawing;
using System.ComponentModel;

namespace Camalon.Drawing
{

	/// <summary>
	/// The CapStyle enumeration specifies the type of graphic shape to use on the end of a 
	/// line drawn with a ShapePen object. 
	/// </summary>
    [Editor("Camalon.Drawing.Design.CapStyleEditor, Camalon.Drawing.Design", typeof(System.Drawing.Design.UITypeEditor))]
    public enum CapStyle
	{
		/// <summary>
		/// Specifies a triangular line cap. 
		/// </summary>
		Triangle,
		/// <summary>
		/// Specifies a Right-To-Left triangular line cap.
		/// </summary>
		TriangleRTL,
		/// <summary>
		/// Specifies that the line ends are anchored with a line turned at 90 degrees. 
		/// </summary>
		Line,
		/// <summary>
		/// Specifies that the line ends are anchored with closed arrowheads. 
		/// </summary>
		Arrow,
		/// <summary>
		/// Specifies that the line ends are anchored with closed arrowheads from right to left. 
		/// </summary>
		ArrowRTL,
		/// <summary>
		/// Specifies that the line ends are anchored with open arrowheads. 
		/// </summary>
		ArrowLine,
		/// <summary>
		/// Specifies that the line ends are anchored with open arrowheads from right to left. 
		/// </summary>
		ArrowLineRTL,
		/// <summary>
		/// Specifies that the line ends are anchored with a diamond (a square turned at 45 degrees). 
		/// </summary>
		Diamond,
		/// <summary>
		/// Specifies that the line ends are anchored with a circle. 
		/// </summary>
		Round,
		/// <summary>
		/// Specifies that the line ends are anchored with a square.
		/// </summary>
		Square,
		/// <summary>
		/// No cap used at the end of the line
		/// </summary>
		None,
		/// <summary>
		/// Specifies that the line ends are anchored with a semicircle.
		/// </summary>
		Semiround,
		/// <summary>
		/// Specifies that the line ends are anchored with a semicircle from right to left.
		/// </summary>
		SemiroundRTL,
		/// <summary>
		/// Specifies that the line ends are anchored with a opening parenthesis.
		/// </summary>
		Parenthesis,
		/// <summary>
		/// Specifies that the line ends are anchored with a closing parenthesis.
		/// </summary>
		ParenthesisRTL,
		/// <summary>
		/// Specifies that the line ends are anchored with an isosceles trapezoid. An isosceles trapezoid is 
		/// a quadrilateral with exactly one pair of parallel sides and two non-parallel sides the same length.
		/// </summary>
		Trapezoid,
		/// <summary>
		/// Specifies that the line ends are anchored with an isosceles trapezoid drawn from right to left.
		/// </summary>
		TrapezoidRTL,
		/// <summary>
		/// Specifies a circular cap. The center of the circle is the last point in the line. 
		/// The diameter of the circle is the line width. 
		/// </summary>
		RoundFitWidth,
		/// <summary>
		/// Specifies a triangular cap. The base of the triangle is the last point in the line. 
		/// The base of the triangle is the line width. 
		/// </summary>
		TriangleFitWidth,
		Moon,
		MoonRTL,
		Bracket,
		BracketRTL,
		CurlyBracket,
		CurlyBracketRTL,
		ClosedCurlyBracket,
		ClosedCurlyBracketRTL
		//CrossingLine
		//Conic
	}


    /// <summary>
    /// The CapSize enumeration specifies the size of graphic shape to use on the end of a 
    /// line drawn with a <c>ShapePen</c> object. 
    /// </summary>
    /// <remarks>The Size is relative to the width of the line</remarks>
	public enum CapSize
	{
		SmallSmall,
		Small,
		Normal,
		Large,
		LargeLarge,
		VeryLarge
	}

    /// <summary>
    /// Specifies the alignment of the line cap. 
    /// </summary>
    /// <remarks>If the cap align is set to <c>Center</c>, the cap is centered to the beginning or end point of a line.
    /// Otherwise, the cap is drawn inset to the beginning or end point of a line.</remarks>
	public enum CapAlign
	{
        /// <summary>
        /// 
        /// </summary>
		Inset,
        /// <summary>
        /// 
        /// </summary>
		Center
	}

	/// <summary>
    /// Specifies the available cap styles with which a <c>ShapePen</c> object can end a line. 
	/// </summary>
	[Serializable]
	[TypeConverter(typeof(LineCapStyleConverter))]
	public struct LineCapStyle
	{
	
		private CapSize		_capSize;
		private float		_sizeFactor;
		private CapStyle	_capStyle;
		private CapAlign	_capAlign;
		private float		_lineInset;
		private bool		_fill;

		public LineCapStyle( CapStyle capStyle, CapSize capSize, CapAlign capAlign, float lineInset, bool fill , float sizeFactor)
		{
			_capStyle	= capStyle;
			_capSize	= capSize;
			_capAlign	= capAlign;
			_lineInset	= lineInset;
			_fill		= fill;
			_sizeFactor = sizeFactor;
		}

        /// <summary>
        /// Initializes a new instance of the <see cref="LineCapStyle"/> struct.
        /// </summary>
        /// <param name="capStyle">The  cap style used at the beginning or end of lines.</param>
        /// <param name="capSize">The cap size used at the beginning or end of lines.</param>
        /// <param name="capAlign">The alignment of the line cap.</param>
        /// <param name="lineInset">The line inset value that determines where the painting of the line begins or ends.</param>
        /// <param name="fill">Determines whether the cap should be filled with the pen color or outlined only.</param>
		public LineCapStyle( CapStyle capStyle, CapSize capSize, CapAlign capAlign, float lineInset, bool fill )
			:this( capStyle, capSize, capAlign,  lineInset, fill, 1.0f){}

		public LineCapStyle( CapStyle capStyle, CapSize capSize, CapAlign capAlign, float lineInset)
			:this( capStyle, capSize, capAlign,  lineInset, true, 1.0f){}

		public LineCapStyle( CapStyle capStyle, CapSize capSize, CapAlign capAlign)
			:this( capStyle, capSize, capAlign,  0f, true, 1.0f){}

		public LineCapStyle( CapStyle capStyle, CapSize capSize)
			:this( capStyle, capSize, CapAlign.Inset,  0f, true, 1.0f){}

		public LineCapStyle( CapStyle capStyle)
			:this( capStyle, CapSize.Normal, CapAlign.Inset,  0f, true, 1.0f){}



        /// <summary>
        /// Gets or sets the  cap style used at the beginning or end of lines.
        /// </summary>
        /// <value>The cap style.</value>
		[DefaultValue( CapStyle.None)]
		[Description(" The cap style used at the beginning or end of lines drawn with this ShapePen object.")]
		public CapStyle Style
		{
			get	{	return _capStyle;	}
			set	{	_capStyle = value;	}
		}


        /// <summary>
        /// Gets or sets the cap size used at the beginning or end of lines.
        /// </summary>
        /// <value>The cap size.</value>
		[DefaultValue( CapSize.Normal)]
		[Description(" The cap size used at the beginning or end of lines drawn with this ShapePen object.")]
		public CapSize Size
		{
			get	{	return _capSize;	}
			set	{	_capSize = value;	}
		}


        /// <summary>
        /// Gets or sets the alignment of the line cap.
        /// </summary>
        /// <value>The align.</value>
		[DefaultValue( CapAlign.Inset )]
		[Description(" Alignment of the line cap")]
		public CapAlign Align
		{
			get	{	return _capAlign;	}
			set	{	_capAlign = value;	}
		}


        /// <summary>
        /// Gets or sets the line inset value that determines where the painting of the line begins or ends.
        /// </summary>
        /// <value>The line inset.</value>
		[DefaultValue(0f)]
		[Description("Value that determines where the painting of the line begins or ends.")]
		public float LineInset
		{
			get	{	return _lineInset;	}
			set {	_lineInset = value;	}
		}

        /// <summary>
        /// Gets or sets a to Determines whether the cap should be filled with the pen color or outlined only.
        /// </summary>
        /// <value><c>true</c> if filled; otherwise, <c>false</c>.</value>
		[DefaultValue(true)]
		[Description("Determines whether the cap should be filled with the pen color or outlined only.")]
		public bool Filled
		{
			get	{	return _fill;	}
			set	{	_fill = value;	}
		}

        /// <summary>
        /// Gets or sets the value that determines the value to scale the cap size.
        /// </summary>
        /// <value>The size factor.</value>
		[DefaultValue(1.0f)]
		[Description("Value that determines the value to scale the cap size.")]
		public float SizeFactor
		{
			get	{	return _sizeFactor;	}
			set 
			{
				if( value <= 0) value = 1.0f;
				_sizeFactor = value;	
			}
		}


        /// <summary>
        /// Gets a value indicating whether this instance is default.
        /// </summary>
        /// <value>
        /// 	<c>true</c> if this instance is default; otherwise, <c>false</c>.
        /// </value>
		[Browsable( false)]
		public bool IsDefault
		{
			get{ return this == LineCapStyle.Default;}
		}

        /// <summary>
        /// Gets the default LineCapStyle.
        /// </summary>
        /// <value>The default.</value>
		public static LineCapStyle Default
		{
			get{ return new LineCapStyle( CapStyle.None );}
		}


		#region operatoren

        /// <summary>
        /// Returns the fully qualified type name of this instance.
        /// </summary>
        /// <returns>
        /// A <see cref="T:System.String"/> containing a fully qualified type name.
        /// </returns>
		public override string ToString()
		{
			return String.Format( "{0}; {1}; {2}; {3}; {4}; {5}", _capStyle, _capSize, _capAlign, _lineInset, _fill, _sizeFactor);
		}

        /// <summary>
        /// Indicates whether this instance and a specified object are equal.
        /// </summary>
        /// <param name="obj">Another object to compare to.</param>
        /// <returns>
        /// true if <paramref name="obj"/> and this instance are the same type and represent the same value; otherwise, false.
        /// </returns>
		public override bool Equals(object obj)
		{
			if(!( obj is LineCapStyle)) return false;

			return  this == (LineCapStyle)obj;
		}

        /// <summary>
        /// overridden
        /// </summary>
		public bool Equals(LineCapStyle value)
		{
			return  this == value;
		}

        /// <summary>
        /// Returns the hash code for this instance.
        /// </summary>
        /// <returns>
        /// A 32-bit signed integer that is the hash code for this instance.
        /// </returns>
		public override int GetHashCode()
		{
			return 
				_capSize.GetHashCode()^
				_capAlign.GetHashCode()^
				_lineInset.GetHashCode()^
				_capStyle.GetHashCode()^
				_fill.GetHashCode()^
				_capSize.GetHashCode();
		}

		public static bool operator ==(	LineCapStyle value1,LineCapStyle value2	)
		{
			return 
				value1.Align == value2.Align && 
				value1.Style == value2.Style && 
				value1.LineInset == value2.LineInset && 
				value1.Size == value2.Size &&
				value1.Filled == value2.Filled &&
				value1.SizeFactor == value2.SizeFactor;
		}

		public static bool operator !=(	LineCapStyle value1,LineCapStyle value2	)
		{
			return !(value1== value2);
		}
		#endregion operatoren


	}
}
